package com.springx.examples.showcase.common.spring.token;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
/**
 * 表单管理器实现类
 *
 * @author tancheng
 */
@Controller
public class FormManagerImpl implements FormManager {
    private static final String SESSION_KEY_OF_FROMS = "forms_in_session";
    /** 表单最大个数 */
    private int                 maxFormNum           = 10;
    /**
     * 生成一个新的表单，如果目前表单个数大于设定的最大表单数则先删除最早的一个表单。<br>
     */
    public Form createForm(HttpServletRequest request) {
        Form form = new Form(RandomStringUtils.randomAlphanumeric(32));
        Map<String, Form> forms = getForms(request);
        synchronized (forms) {
            // 如果目前表单个数大于等于最大表单数，那么删除最老的表单，添加新表单。
            if (forms.size() >= maxFormNum) {
                removeOldestForm(request);
            }
            forms.put(form.getToken(), form);
        }
        return form;
    }
    /**
     * 删除token并且重新创建一个
     * @param token
     */
    public void removeAndCreateToken(HttpServletRequest request,String token){
    	this.removeToken(request, token);
    	Form form=createForm(request);
		request.setAttribute(Form.FORM_TOKEN_FIELD_NAME, form.getToken());
    }
    
    /**
     * 判断表单是否存在。如果token为null，直接返回false。
     *
     * @see #getForms(javax.servlet.http.HttpServletRequest)
     */
    public boolean hasForm(HttpServletRequest request, String token) {
        if (token == null) {
            return false;
        }
        return getForms(request).containsKey(token);
    }
    
    
    
    /**
     * 访问参数中是否存在表单Token。
     */
    public boolean hasFormToken(HttpServletRequest request) {
        String formToken = request.getParameter(Form.FORM_TOKEN_FIELD_NAME);
        return StringUtils.isNotBlank(formToken);
    }
    
    
    /**
     * 销毁一个表单
     */
    public void removeToken(HttpServletRequest request, String token) {
        getForms(request).remove(token);
    }
    /**
     * 打印表单信息。
     */
    public String dumpForm(HttpServletRequest request, String token) {
        Form form = getForms(request).get(token);
        if (form == null) {
            return "null";
        }
        return form.toString();
    }
   
    
    
   
    /**
     * 获得目前session中的表单列表。
     *
     * @return 返回的Map中以表单的token为键，Form对象为值
     */
    @SuppressWarnings("unchecked")
    protected Map<String, Form> getForms(HttpServletRequest request) {
        Map<String, Form> formsInSession = null;
        Subject subject=SecurityUtils.getSubject();
        if(subject==null){
        	return new HashMap<String, Form>();
        }else{
        	Session session=subject.getSession();
        	synchronized (session) {
                formsInSession = (Map<String, Form>) session.getAttribute(SESSION_KEY_OF_FROMS);
                if (formsInSession == null) {
                    formsInSession = new HashMap<String, Form>();
                    session.setAttribute(SESSION_KEY_OF_FROMS, formsInSession);
                }
            }
        }
        return formsInSession;
    }
    /**
     * 删除最老的Form
     *
     * @see #removeToken(javax.servlet.http.HttpServletRequest, String)
     */
    protected void removeOldestForm(HttpServletRequest request) {
        List<Form> forms = new ArrayList<Form>(getForms(request).values());
        if (!forms.isEmpty()) {
	        Form oldestForm = forms.get(0);
	        for (Form form : forms) {
	            if (form.getCreateTime().before(oldestForm.getCreateTime())) {
	                oldestForm = form;
	            }
	        }
	        removeToken(request, oldestForm.getToken());
        }
    }
    public void setMaxFormNum(int maxFormNum) {
        this.maxFormNum = maxFormNum;
    }
}